
#ifndef RAY_H
#define RAY_H

#define P_OFFSET 0
#define D_OFFSET 4
#define VIEW_RAY 0
#define SHADOW_RAY 1

#include"algfloat.h"

struct Ray{
  float data[2*8];
  float normal[4];
  float color[3];
  float obj_color[3];
  float obj_shine;
  float obj_reflec;
  bool obj_nospec;
  float tmax;
  float tmin;
  int shadow_obj;
  bool shadow_mode;
  float shade_complete;
  int pposx;
  int pposy;
  bool ref;
  inline float* GetP (int level)
  {
    return &data[(level)*8+P_OFFSET];
  };
  inline float* GetD (int level)
  {
    return &data[(level)*8+D_OFFSET];
  };
  inline void CalcPoint (int level, float t, float* res)
  {
    float *p = GetP(level); 
    float *d = GetD(level); 
    res[0] = p[0] + t*d[0];
    res[1] = p[1] + t*d[1];
    res[2] = p[2] + t*d[2];
    res[3] = 1.0;
  }
  bool Reflect ()
  {
    if(shade_complete==1.0)
      return false;
    AFScale(-1,GetD(VIEW_RAY));
    float reflected_vec[4];
    AFReflect(GetD(VIEW_RAY), normal, reflected_vec);
    reflected_vec[3]=0.0;
    AFNorm(reflected_vec);
    AFCopy(reflected_vec, GetD(VIEW_RAY));
    AFCopy(GetP(SHADOW_RAY), GetP(VIEW_RAY));
    tmax = -1.0;
    tmin = -1.0;
    shadow_obj = -1.0;
    shadow_mode = false;
    return true;
  }
};

#endif
